package com.qinhao.loveCrowdFunding.controller;

import com.apistd.uni.Uni;
import com.apistd.uni.UniException;
import com.apistd.uni.UniResponse;
import com.apistd.uni.sms.UniMessage;
import com.apistd.uni.sms.UniSMS;
import com.qinhao.loveCrowdFunding.pojo.*;
import com.qinhao.loveCrowdFunding.req.*;
import com.qinhao.loveCrowdFunding.resp.*;
import com.qinhao.loveCrowdFunding.resp.GetMonitorResponse;
import com.qinhao.loveCrowdFunding.service.SystemDataService;
import com.qinhao.loveCrowdFunding.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.monitor.v20180724.MonitorClient;
import com.tencentcloudapi.monitor.v20180724.models.*;


import com.qinhao.loveCrowdFunding.enums.ResponseCodeEnum;
import com.qinhao.loveCrowdFunding.service.UserLoginService;
import com.qinhao.loveCrowdFunding.service.UserRegistryService;

import java.util.*;


@RestController
@CrossOrigin
@RequestMapping("/basic")
public class BasicEntranceController {
    @Autowired
    private UserLoginService userLoginService;
    @Autowired
    private UserRegistryService userRegistryService;
    private static final Logger log = Logger.getLogger(BasicEntranceController.class);
    @Autowired
    private SystemDataService systemDataService;

    private UserLoginResponse userLoginResponse = new UserLoginResponse();
    private UserRegistryResponse userRegistryResponse = new UserRegistryResponse();

    @RequestMapping("/login")
    public UserLoginResponse basicLogin(@RequestBody UserLoginRequest userLoginRequest) {
        try {
            if (userLoginRequest.getName() == null) {
                userLoginResponse.setResponseCode(ResponseCodeEnum.USERNAMEISNULL.getCode());
            } else if (userLoginRequest.getPhone() == null) {
                userLoginResponse.setResponseCode(ResponseCodeEnum.PHONEISNULL.getCode());
            } else if (userLoginRequest.getPassword() == null) {
                userLoginResponse.setResponseCode(ResponseCodeEnum.PASSWORDISNULL.getCode());
            } else {
                // 明文转为MD5
                String encrypt2ToMD5 = MD5Util.encrypt2ToMD5(userLoginRequest.getPassword());
                userLoginRequest.setPassword(encrypt2ToMD5);
                UserLoginDTO userLoginDTO = userLoginService.queryUserByLogin(userLoginRequest);
                UserLoginVO userLoginVO = new UserLoginVO();
                if (userLoginDTO != null) {
                    BeanUtils.copyProperties(userLoginDTO, userLoginVO);
                    BeanUtils.copyProperties(userLoginVO, userLoginResponse);
                }
                userLoginResponse.setResponseCode(ResponseCodeEnum.SUCCESS.getCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
            userLoginResponse.setResponseCode(ResponseCodeEnum.FAIL.getCode());
        } finally {
            return userLoginResponse;
        }
    }

    @RequestMapping("/registry")
    public UserRegistryResponse basicRegistry(@RequestBody UserRegistryRequest userRegistryRequest) {
        try {
            if (userRegistryRequest.getPhone() == null || StringUtils.deleteWhitespace(userRegistryRequest.getPhone()) == "") {
                userRegistryResponse.setResponseCode(ResponseCodeEnum.PHONEISNULL.getCode());
            } else if (userRegistryRequest.getName() == null || StringUtils.deleteWhitespace(userRegistryRequest.getName()) == "") {
                userRegistryResponse.setResponseCode(ResponseCodeEnum.USERNAMEISNULL.getCode());
            } else if (userRegistryRequest.getPassword() == null || StringUtils.deleteWhitespace(userRegistryRequest.getPassword()) == "") {
                userRegistryResponse.setResponseCode(ResponseCodeEnum.PASSWORDISNULL.getCode());
            } else if (userRegistryService.queryName(userRegistryRequest).getId() != null) {
                userRegistryResponse.setResponseCode(ResponseCodeEnum.USERNAMEREPEAT.getCode());
            } else if (userRegistryService.queryPhone(userRegistryRequest).getId() != null) {
                userRegistryResponse.setResponseCode(ResponseCodeEnum.USERPHONEREPEAT.getCode());
            } else {
                // 明文转为MD5
                String encrypt2ToMD5 = MD5Util.encrypt2ToMD5(userRegistryRequest.getPassword());
                userRegistryRequest.setPassword(encrypt2ToMD5);
                UserRegistryDTO userRegistryDTO = userRegistryService.insertUserByRegistry(userRegistryRequest);
                UserRegistryVO userRegistryVO = new UserRegistryVO();
                if (userRegistryDTO != null) {
                    BeanUtils.copyProperties(userRegistryDTO, userRegistryVO);
                    BeanUtils.copyProperties(userRegistryVO, userRegistryResponse);
                }
                userRegistryResponse.setResponseCode(ResponseCodeEnum.SUCCESS.getCode());
            }
        } catch (Exception e) {
            userRegistryResponse.setResponseCode(ResponseCodeEnum.FAIL.getCode());
            e.printStackTrace();
        } finally {
            return userRegistryResponse;
        }
    }

    @RequestMapping("/adminLoginAuthentication")
    public AdminLoginResponse basicLoginAuth(@RequestBody AdminLoginAuthenticationRequest adminLoginAuthenticationRequest) {
        AdminLoginResponse adminLoginResponse = AdminLoginResponse.builder().build();
        if (AdminLoginUtil.getHashSet().contains(adminLoginAuthenticationRequest.getUserName())) {
            adminLoginResponse.setCode(ResponseCodeEnum.SUCCESS.getCode());
        }else {
            adminLoginResponse.setCode(ResponseCodeEnum.FAIL.getCode());
        }
        log.info(adminLoginAuthenticationRequest.getUserName());
        log.info(AdminLoginUtil.getHashSet().contains(adminLoginAuthenticationRequest.getUserName()));
        return adminLoginResponse;
    }

    @RequestMapping("/registryByPhone")
    public RegistryByPhoneResponse registryByPhone(@RequestBody RegistryByPhoneRequest registryByPhoneRequest) {
        RegistryByPhoneResponse registryByPhoneResponse = RegistryByPhoneResponse.builder().build();
        String ACCESS_KEY_ID = "RkrURuXxbCgzcruJZLwj6ZqVvjKtvVZbFLwwUzFS6dCNSy8Q2";
        // 初始化
        Uni.init(ACCESS_KEY_ID); // 若使用简易验签模式仅传入第一个参数即可
        // 设置自定义参数 (变量短信)
        Map<String, String> templateData = new HashMap<String, String>();
        String number = Generate4RandomNumberUtil.Generate4RandomNumber();
        templateData.put("code", number);
        // 构建信息
        UniMessage message = UniSMS.buildMessage()
                .setTo(registryByPhoneRequest.getPhone())
                .setSignature("怡时光+")
                .setTemplateId("pub_verif_login")
                .setTemplateData(templateData);
            // 发送短信
            try {
                UniResponse res = message.send();
                registryByPhoneResponse.setCode(ResponseCodeEnum.SUCCESS.getCode());
                registryByPhoneResponse.setResult(MD5Util.encrypt2ToMD5(number));
            } catch (UniException e) {
                System.out.println("Error: " + e);
                System.out.println("RequestId: " + e.requestId);
                if (e.code.equals("107111")) {
                    registryByPhoneResponse.setCode(ResponseCodeEnum.PHONEFORMATERROR.getCode());
                } else {
                    registryByPhoneResponse.setCode(ResponseCodeEnum.FAIL.getCode());
                }
            }
            return registryByPhoneResponse;
        }

    @RequestMapping("/updatePassword")
    public UpdatePasswordResponse updatePassword(@RequestBody UpdatePasswordRequest updatePasswordRequest) {
        UpdatePasswordResponse updatePasswordResponse = UpdatePasswordResponse.builder().build();
        try {
            String encrypt2ToMD5 = MD5Util.encrypt2ToMD5(updatePasswordRequest.getPassword());
            updatePasswordRequest.setPassword(encrypt2ToMD5);
            userLoginService.updatePassword(updatePasswordRequest);
            updatePasswordResponse.setCode(ResponseCodeEnum.SUCCESS.getCode());
        } catch (Exception e) {
            updatePasswordResponse.setCode(ResponseCodeEnum.FAIL.getCode());
        }
        return updatePasswordResponse;
    }


    @RequestMapping("/updateNameById")
    public UpdateNameByIdResponse updateNameById(@RequestBody UpdateNameByIdRequest updateNameByIdRequest) {
        UpdateNameByIdResponse updateNameByIdResponse = UpdateNameByIdResponse.builder().build();
        try {
            Boolean aBoolean = userLoginService.updateNameById(updateNameByIdRequest);
            if (aBoolean) {
                updateNameByIdResponse.setCode(ResponseCodeEnum.SUCCESS.getCode());
            } else {
                updateNameByIdResponse.setCode(ResponseCodeEnum.USERNAMEREPEAT.getCode());
            }
        } catch (Exception e) {
           updateNameByIdResponse.setCode(ResponseCodeEnum.FAIL.getCode());
        }
        return updateNameByIdResponse;
    }

    @RequestMapping("/getIntegralBalance")
    public GetIntegralBalanceResponse getIntegralBalance(@RequestBody GetIntegralBalanceRequest getIntegralBalanceRequest) {
        GetIntegralBalanceResponse getIntegralBalanceResponse = GetIntegralBalanceResponse.builder().build();
        try {
            GetIntegralBalanceDTO integralBalanceDTO = userLoginService.getIntegralBalanceByUserId(getIntegralBalanceRequest);
            if (integralBalanceDTO != null) {
                BeanUtils.copyProperties(integralBalanceDTO, getIntegralBalanceResponse);
            }
            getIntegralBalanceResponse.setCode(ResponseCodeEnum.SUCCESS.getCode());
        } catch (Exception e) {
            getIntegralBalanceResponse.setCode(ResponseCodeEnum.FAIL.getCode());
        }
        return getIntegralBalanceResponse;
    }

    // 获得用户积分记录
    @RequestMapping("/getIntegralRecord")
    public GetIntegralRecordResponse getIntegralRecord(@RequestBody GetIntegralRecordRequest getIntegralRecordRequest) {
        GetIntegralRecordResponse getIntegralRecordResponse = GetIntegralRecordResponse.builder().build();
        try {
            List<GetIntegralRecordBO> integralRecord = userLoginService.getIntegralRecord(getIntegralRecordRequest);
            List<IntegralVO> integralRecordTmp = new ArrayList<>();
            for (int i = 0; i < integralRecord.size(); i++) {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(integralRecord.get(i).getIntergralMessage());
                if (integralRecord.get(i).getIntergralChange() < 0) {
                    stringBuilder.append("减少了");
                } else {
                    stringBuilder.append("增加了");
                }
                stringBuilder.append(integralRecord.get(i).getIntergralChange().toString());
                IntegralVO integralVO = IntegralVO.builder().build();
                integralVO.setTitle(stringBuilder.toString());
                integralVO.setStatus(false);
                integralRecordTmp.add(integralVO);
            }
            getIntegralRecordResponse.setCode(ResponseCodeEnum.SUCCESS.getCode());
            getIntegralRecordResponse.setIntegralRecord(integralRecordTmp);
        } catch (Exception e) {
            getIntegralRecordResponse.setCode(ResponseCodeEnum.FAIL.getCode());
        }
        return getIntegralRecordResponse;
    }

    // 获取腾讯云主机监控数据
    @RequestMapping("/getMonitorData")
    public GetMonitorResponse getMonitorData() {
        GetMonitorResponse getMonitorResponse = GetMonitorResponse.builder().build();
        List<MonitorEntity> datasets = new ArrayList<>();
        try{
            // 获取用户数量
            Integer userCount = systemDataService.getUserCount();
            getMonitorResponse.setUserCount(userCount);
            // 获取用户访问量
            Integer visitCount = systemDataService.getVisitCount();
            getMonitorResponse.setVisitCount(visitCount);
            // 获取消息数量
            Integer messageCount = systemDataService.getMessageCount();
            getMonitorResponse.setMessageCount(messageCount);
            // 获取是否需要重新get数据
            Integer getStatus = systemDataService.getSystemDataStatus();
            if (getStatus == 1) {
                log.info("直接获取数据");
                GetMonitorResponse getMonitorResponse1 = SystemDataUtil.getVector().get(0);
                getMonitorResponse.setDatasets(getMonitorResponse1.getDatasets());
                getMonitorResponse.setLabels(getMonitorResponse1.getLabels());
            } else {
                // 实例化一个认证对象，入参需要传入腾讯云账户secretId，secretKey,此处还需注意密钥对的保密
                // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
                Credential cred = new Credential("AKIDITRBgvwmNjqiNp21kEVXKr9C2dy4vXvM", "IMBnCOL3VihT0KPGsJWUCftseASUHsGP");
                // 实例化一个http选项，可选的，没有特殊需求可以跳过
                HttpProfile httpProfile = new HttpProfile();
                httpProfile.setEndpoint("monitor.tencentcloudapi.com");
                // 实例化一个client选项，可选的，没有特殊需求可以跳过
                ClientProfile clientProfile = new ClientProfile();
                clientProfile.setHttpProfile(httpProfile);
                // 实例化要请求产品的client对象,clientProfile是可选的
                MonitorClient client = new MonitorClient(cred, "ap-shanghai", clientProfile);
                // 获取25分钟内的基础 CPU 使用率，并且格式化数据
                DataPoint[] baseCpuUsages = getMonitorDataByPattern("BaseCpuUsage", client);
                Long[] timestamps = baseCpuUsages[0].getTimestamps();
                List<String> monitorLabels = TimeUtil.getMonitorLabels(timestamps);
                getMonitorResponse.setLabels(monitorLabels);
                Float[] values = baseCpuUsages[0].getValues();
                Float[] fiveResult = getFiveResult(values);
                MonitorEntity monitorEntity = MonitorEntity.builder().build();
                monitorEntity.setLabel("基础CPU使用率");
                monitorEntity.setData(fiveResult);
                datasets.add(monitorEntity);
                //  获取25分钟内的外网出带宽，并且格式化数据
                baseCpuUsages = getMonitorDataByPattern("WanOuttraffic", client);
                values = baseCpuUsages[0].getValues();
                fiveResult = getFiveResult(values);
                monitorEntity = MonitorEntity.builder().build();
                monitorEntity.setLabel("外网出带宽");
                monitorEntity.setData(fiveResult);
                datasets.add(monitorEntity);
                // 获取25分钟内的外网入带宽，并且格式化数据
                baseCpuUsages = getMonitorDataByPattern("WanIntraffic", client);
                values = baseCpuUsages[0].getValues();
                fiveResult = getFiveResult(values);
                monitorEntity = MonitorEntity.builder().build();
                monitorEntity.setLabel("外网入带宽");
                monitorEntity.setData(fiveResult);
                datasets.add(monitorEntity);
                getMonitorResponse.setDatasets(datasets);
                SystemDataUtil.getVector().add(0, getMonitorResponse);
                // 获取是否需要重新get数据
                systemDataService.updateSystemDataStatus();
                log.info("更新了Vector");
            }
            getMonitorResponse.setCode(ResponseCodeEnum.SUCCESS.getCode());
        } catch (TencentCloudSDKException e) {
            log.error(e.toString());
            getMonitorResponse.setCode(ResponseCodeEnum.FAIL.getCode());
        } catch (Exception e)  {
            getMonitorResponse.setCode(ResponseCodeEnum.FAIL.getCode());
            log.error(e.toString());
        }
        return getMonitorResponse;
    }

    private DataPoint[] getMonitorDataByPattern(String pattern, MonitorClient client) throws TencentCloudSDKException{
        // 实例化一个请求对象,每个接口都会对应一个request对象
        GetMonitorDataRequest req = new GetMonitorDataRequest();
        req.setNamespace("QCE/CVM");
        req.setMetricName(pattern);
        req.setPeriod(300L);
        req.setStartTime(TimeUtil.getISO8601Timestamp(new Date()));
        Instance[] instances1 = new Instance[1];
        Instance instance1 = new Instance();
        Dimension[] dimensions1 = new Dimension[1];
        Dimension dimension1 = new Dimension();
        dimension1.setName("InstanceId");
        dimension1.setValue("ins-622aw8ej");
        dimensions1[0] = dimension1;
        instance1.setDimensions(dimensions1);
        instances1[0] = instance1;
        req.setInstances(instances1);
        // 返回的resp是一个GetMonitorDataResponse的实例，与请求对象对应
        GetMonitorDataResponse response = client.GetMonitorData(req);
       return response.getDataPoints();
    }

    private Float[] getFiveResult(Float[] values) {
        Float[] floats = new Float[5];
        for (int i = 0; i < values.length; i++) {
            floats[i] = values[i];
            if (i == 4) {
                break;
            }
        }
        return floats;
    }

}
